using System;
using System.Collections.Generic;
using System.Text;
using GarageGames.Torque.T2D;
using GarageGames.Torque.Materials;
using Xyne.Components;
using Microsoft.Xna.Framework;
using GarageGames.Torque.Core;
using Microsoft.Xna.Framework.Graphics;
using GarageGames.Torque.Util;
using Xyne.Objects;
using GarageGames.Torque.Lighting;

namespace Xyne.Templates.PuzzlePieceTemplate
{
    public class PuzzlePiece : T2DStaticSprite
    {
        private static PuzzlePiece template = new PuzzlePiece();

        private bool selectable = false;
        private bool selected = false;
        private PuzzlePieceColorEnum id = PuzzlePieceColorEnum.None;
        private bool inPlay = false;
        private bool glow = false;

        public Boolean InPlay
        {
            get
            {
                return inPlay;
            }

            set
            {
                inPlay = value;
            }
        }

        public Boolean Selectable
        {
            get { return selectable; }
            set { selectable = value; }
        }

        public Boolean Selected
        {
            get { return selected; }
            set { selected = value; }
        }

        public PuzzlePieceColorEnum ID
        {
            get { return id; }
            set { id = value; }
        }

        public static PuzzlePiece Template
        {
            get { return template; }
        }

        public PuzzlePiece()
        {
            // Set the template and name
            IsTemplate = true;
            Name = Game.PuzzlePieceName;

            // Size and collision parameters
            Layer = Game.PuzzlePieceLayer;
            Size = new Vector2(Game.PuzzlePieceWidth, Game.PuzzlePieceHeight);
            ObjectType = TorqueObjectDatabase.Instance.GetObjectType(Name);
            Collision.CollidesWith = TorqueObjectDatabase.Instance.GetObjectType(Name) + TorqueObjectDatabase.Instance.GetObjectType(Game.PlayerPiecesName);
            Collision.ResolveCollision = new T2DResolveCollisionDelegate(OnCollision);
            T2DWorldLimitComponent limit = new T2DWorldLimitComponent();
            limit.WorldLimitResolveCollision = new T2DResolveCollisionDelegate(OnWorldCollision);
            Components.AddComponent(limit);

            // Remove current images
            ReadOnlyArray<T2DCollisionImage> images = Collision.Images;
            foreach (T2DCollisionImage collisionImage in images)
            {
                Collision.RemoveImage((T2DCollisionImage)collisionImage);
            }

            // Create a custom collision image
            T2DPolyImage image = new T2DPolyImage();
            Vector2[] points = new Vector2[4];
            points[0] = new Vector2(-0.9f, -1.0f);
            points[1] = new Vector2(-0.9f, 1.0f);
            points[2] = new Vector2(0.9f, 1.0f);
            points[3] = new Vector2(0.9f, -1.0f);
            image.CollisionPolyBasis = points;
            Collision.InstallImage(image);
        }

        public override void CopyTo(TorqueObject obj)
        {
            base.CopyTo(obj);
        }

        public static void OnCollision(T2DSceneObject ourObject, T2DSceneObject theirObject, ref T2DCollisionInfo info,
                    T2DCollisionMaterial physicsMaterial, bool handleBoth)
        {
            // If the piece lands on the player piece or other piece
            if (info.Normal.Y < 0 && (int)Math.Round(theirObject.Position.X) == (int)Math.Round(ourObject.Position.X))
            {
                ourObject.WarpToPosition(new Vector2(ourObject.Position.X, theirObject.Position.Y - (theirObject.Size.Y / 2) - (ourObject.Size.Y / 2)), 0);
                ourObject.Physics.VelocityY = theirObject.Physics.VelocityY;
            }
        }

        private void OnWorldCollision(T2DSceneObject ourObject, T2DSceneObject theirObject, ref T2DCollisionInfo info,
                    T2DCollisionMaterial physicsMaterial, bool handleBoth)
        {
            // If the piece lands on the bottom of the world
            if (info.Normal.Y < 0)
            {
                ourObject.WarpToPosition(new Vector2(ourObject.Position.X, ourObject.WorldLimit.MoveLimitMax.Y - (ourObject.Size.Y / 2)), 0);
                ourObject.Physics.VelocityY = 0;
            }
        }

        public void SetPuzzlePieceColor(PuzzlePieceColorEnum color)
        {
            id = color;
            Material = PuzzlePieceMaterialManager.Instance.GetPuzzlePieceMaterial(color);
        }

        #region Static Accessors
        public static PuzzlePiece GetDisplayPuzzlePiece(PuzzlePieceColorEnum color)
        {
            PuzzlePiece puzzlePiece = (PuzzlePiece)PuzzlePiece.Template.Clone();
            puzzlePiece.Visible = true;
            puzzlePiece.CollisionsEnabled = false;
            puzzlePiece.SetPuzzlePieceColor(color);
            return puzzlePiece;
        }
        #endregion      

    }
}
